package com.heatup.apt.api.controller;

import com.heatup.apt.api.service.AccessService;
import com.heatup.apt.api.service.CoachService;
import com.heatup.apt.api.service.StoreService;
import com.heatup.apt.api.service.UserService;
import com.heatup.apt.common.constants.ErrorCodeConstants;
import com.heatup.apt.common.constants.UserConstants;
import com.heatup.apt.common.dao.SmsLogMapper;
import com.heatup.apt.common.util.CheckCodeUtil;
import com.heatup.apt.common.util.JsonTools;
import com.heatup.apt.common.util.ResponseTools;
import com.heatup.apt.common.util.SmsUtil;
import com.heatup.apt.model.DoorAccessPwd;
import com.heatup.apt.model.SmsLog;
import com.heatup.apt.model.api.ApiResultModel;
import com.heatup.apt.model.coach.CoachInfo;
import com.heatup.apt.model.management.SysUser;
import com.heatup.apt.model.store.StoreInfo;
import com.heatup.apt.model.user.UserInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 门禁设备控制器
 * Created by Blank on 2016-10-13.
 */
@Controller
@RequestMapping(value = "/door")
public class AccessController extends BaseController {

    private static final Logger log = LoggerFactory.getLogger(AccessController.class);


    @Resource
    private AccessService accessService;

    @Resource
    private CoachService coachService;

    @Resource
    private UserService userService;

    @Resource
    private StoreService storeservice;

    @Resource
    private SmsLogMapper smsLogMapper;

//    /**
//     * 门禁开门请求
//     *
//     * @param Pin      密码(需10转16进制并反转数字)
//     * @param Card     卡号
//     * @param Serial   门禁设备唯一标识
//     * @param SuperPIN 是否为超级密码
//     * @param Reader
//     * @param SuperPIN
//     * @param ActIndex
//     * @return
//     */
//    @Deprecated
//    @RequestMapping(value = "/access", produces = "text/html;charset=gb2312")
//    public void dataAcs(HttpServletResponse response, String Pin, String Card, Integer SuperPIN, String Serial, String Reader, String Status, String ActIndex, String Act, String Index) {
//        if (Card == null) {
//            Card = Pin;
//        }
//
//        String result;
//
//        Card = Long.toHexString(Long.valueOf(Card));
//        StringBuilder cardN = new StringBuilder();
//        cardN.append(Card.replaceAll("f", "")).reverse();
//        String isSuperPIN = " 不是超级密码";
//        if (SuperPIN != null && SuperPIN == 1) {
//            isSuperPIN = " 超级密码";
//        }
//        log.info("门禁开门请求 参数------------>>>> 密码" + cardN.toString() + isSuperPIN + " 设备状态 " + Status + " 设备ID" + Serial + " ActIndex " + ActIndex);
//
//        boolean isRight = accessService.checkQRCodePwd(cardN.toString(), Serial);
//        //AcsRes 返回"1"即可开门
//        if (isRight) {//开门
//            result = "{Card:'" + Card + "',Serial:'" + Serial + "',ActIndex:'" + ActIndex + "',Reader:'1',AcsRes:'1',Time:'5',Event:'10',Note:'欢迎光临',Name:'檬运动'}";
//        } else {//拒绝
//            result = "{Card:'" + Card + "',Serial:'" + Serial + "',ActIndex:'" + ActIndex + "',Reader:'1',AcsRes:'0',Time:'5',Event:'10',Note:'密码错误',Name:'檬运动'}";
//        }
//        //记录密码使用
//        accessService.updateAccessDevicePWDUsedCount(Serial, cardN.toString(), isRight, SuperPIN != null && (SuperPIN == 1));
//        log.info("result ========> " + result);
//        ResponseTools.writeResult(response, result, "gb2312");
//    }



    /**
     * 发送验证码
     *
     * @param mobile 手机号码
     * @return
     */
    @RequestMapping(value = "/send", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    private String send(@RequestParam() String mobile,
                        @RequestParam(defaultValue = "") String callback) {

        Integer userId = getUserId();

        ApiResultModel<Map<String, Object>> apiResultModel = new ApiResultModel<>();
        apiResultModel.setLogined(this.isLogined());

        //未登陆
        if (userId == null) {
            apiResultModel.setRet(ApiResultModel.RET_ERROR);
            apiResultModel.setErrorCode(ErrorCodeConstants.Code.USER_NOT_LOGIN.getCode());
            apiResultModel.setMsg(ErrorCodeConstants.Code.USER_NOT_LOGIN.getMessage());
            return ResponseTools.CallBackResultJsonP(JsonTools.jsonSer(apiResultModel), callback);
        }


        try {
            //检查发送间隔
            Object lastSend = this.getSession(SESSION_KEY_CHECK_CODE_LAST_SEND);
            if (lastSend != null) {
                long lastSendTime = (long) lastSend;
                long currentTime = System.currentTimeMillis();
                long seconds = (currentTime - lastSendTime) / DateUtils.MILLIS_PER_SECOND;
                if (seconds < UserConstants.SEND_CHECK_CODE_INTERVAL) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("nextSendSecond", seconds);
                    apiResultModel.setData(map);
                    apiResultModel.setRet(ApiResultModel.RET_ERROR);
                    apiResultModel.setErrorCode(ErrorCodeConstants.Code.SMS_SEND_TOO_MUCH.getCode());
                    apiResultModel.setMsg(ErrorCodeConstants.Code.SMS_SEND_TOO_MUCH.getMessage());

                    return ResponseTools.CallBackResultJsonP(JsonTools.jsonSer(apiResultModel), callback);
                }
            }

            //检查发送限额
            int todayMyCount = smsLogMapper.querySmsCountByUserMobile(mobile);
            if (todayMyCount > UserConstants.CHECK_CODE_MAX_SEND_COUNT) {

                Map<String, Object> map = new HashMap<>();
                apiResultModel.setData(map);
                apiResultModel.setRet(ApiResultModel.RET_ERROR);
                apiResultModel.setErrorCode(ErrorCodeConstants.Code.SMS_SEND_OVER_LIMIT.getCode());
                apiResultModel.setMsg(ErrorCodeConstants.Code.SMS_SEND_OVER_LIMIT.getMessage());

                return ResponseTools.CallBackResultJsonP(JsonTools.jsonSer(apiResultModel), callback);
            }

            Map<String, Object> map = new HashMap<>();

            int checkCode = CheckCodeUtil.getCheckCode();
            boolean sendResult = SmsUtil.sendCheckCode(mobile, checkCode + "");

            //发送记录
            SmsLog smsLog = new SmsLog();
            smsLog.setMobile(mobile);
            smsLog.setCheckCode(checkCode + "");
            smsLog.setUserId(userId);
            smsLog.setSendTime(new Date());
            smsLog.setSendResult(sendResult ? 1 : 2);
            smsLog.setSendType(1);
            smsLogMapper.insertSelective(smsLog);
            log.info("记录教练/系统用户 发送验证码 " + smsLog.toString());
            this.setSession(SESSION_KEY_MOBILE, mobile);
            this.setSession(SESSION_KEY_CHECK_CODE, checkCode);
            this.setSession(SESSION_KEY_CHECK_CODE_LAST_SEND, System.currentTimeMillis());
            map.put("nextSendSecond", UserConstants.SEND_CHECK_CODE_INTERVAL);

            apiResultModel.setData(map);
            apiResultModel.setRet(ApiResultModel.RET_SUCCESS);
            apiResultModel.setMsg("");
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.toString() + e.getCause());
            apiResultModel.setRet(ApiResultModel.RET_ERROR);
            apiResultModel.setErrorCode(ErrorCodeConstants.Code.SYSTEM_ERROR_EXCEPTION.getCode());
            apiResultModel.setMsg(ErrorCodeConstants.Code.SYSTEM_ERROR_EXCEPTION.getMessage() + e.getMessage());
        }
        return ResponseTools.CallBackResultJsonP(JsonTools.jsonSer(apiResultModel), callback);
    }


    /**
     * 教练/系统用户 手机绑定(点击确认请求)
     *
     * @param mobile
     * @return
     */
    @RequestMapping(value = "/coach_bind", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String toCoachBind(@RequestParam String mobile,
                              @RequestParam Integer checkCode,
                              @RequestParam(defaultValue = "") String callback) {

        //校验短信验证码
        ApiResultModel<Map<String, Object>> apiResultModel = new ApiResultModel<>();
        apiResultModel.setLogined(this.isLogined());
        UserInfo user = getUserInfo();
        //未登陆
        if (user == null) {
            log.info("教练/系统用户 未登陆");
            apiResultModel.setRet(ApiResultModel.RET_ERROR);
            apiResultModel.setErrorCode(ErrorCodeConstants.Code.USER_NOT_LOGIN.getCode());
            apiResultModel.setMsg(ErrorCodeConstants.Code.USER_NOT_LOGIN.getMessage());
            return ResponseTools.CallBackResultJsonP(JsonTools.jsonSer(apiResultModel), callback);
        }

        try {
            //有效期验证
            Object sysCode = this.getSession(SESSION_KEY_CHECK_CODE);
            Object lastSend = this.getSession(SESSION_KEY_CHECK_CODE_LAST_SEND);
            if (sysCode == null || lastSend == null) {
                apiResultModel.setRet(ApiResultModel.RET_ERROR);
                apiResultModel.setErrorCode(ErrorCodeConstants.Code.SMS_CHECK_CODE_NULL.getCode());
                apiResultModel.setMsg(ErrorCodeConstants.Code.SMS_CHECK_CODE_NULL.getMessage());

                return ResponseTools.CallBackResultJsonP(JsonTools.jsonSer(apiResultModel), callback);
            }

            long lastSendTime = (long) lastSend;
            long currentTime = System.currentTimeMillis();
            long seconds = (currentTime - lastSendTime) / DateUtils.MILLIS_PER_SECOND;
            if (seconds > UserConstants.CHECK_CODE_TIMEOUT) {
                apiResultModel.setRet(ApiResultModel.RET_ERROR);
                apiResultModel.setErrorCode(ErrorCodeConstants.Code.SMS_CHECK_CODE_INVALID.getCode());
                apiResultModel.setMsg(ErrorCodeConstants.Code.SMS_CHECK_CODE_INVALID.getMessage());
                return ResponseTools.CallBackResultJsonP(JsonTools.jsonSer(apiResultModel), callback);
            }

            //验证码验证
            if (!sysCode.toString().equals(checkCode.toString())) {
                log.info("教练/系统用户 验证码错误 ---->" + "系统生成 " + seconds + " 用户输入 " + checkCode);
                apiResultModel.setRet(ApiResultModel.RET_ERROR);
                apiResultModel.setErrorCode(ErrorCodeConstants.Code.SMS_CHECK_CODE_ERROR.getCode());
                apiResultModel.setMsg(ErrorCodeConstants.Code.SMS_CHECK_CODE_ERROR.getMessage());

            } else {
                apiResultModel.setRet(ApiResultModel.RET_SUCCESS);
                apiResultModel.setMsg("验证成功");
                log.info("教练/系统用户 验证成功");

                //查询教练是否存在

                CoachInfo coach = null;
                SysUser sysUser = null;
                if (user != null && StringUtils.isNotBlank(mobile)) {
                    log.info("查询用户是否为教练");
                    //查询用户是否为教练
                    coach = coachService.queryCoachByMobile(mobile);
                }
                if (coach != null) {
                    log.info("如果是教练 并且用户表中手机号码为空 将教练表中的手机号码更新到用户表中");
                    //如果是教练 并且用户表中手机号码为空 将教练表中的手机号码更新到用户表中
                    if (StringUtils.isBlank(user.getMobile())) {
                        log.info("教练 未空说明未绑定");
                        //未空说明未绑定
                        userService.updateMobile(user.getId(), mobile);

                        UserInfo userInfo = userService.selectById(user.getId());
                        setUserInfo(userInfo);


                        log.info("教练 跳转到请求密码界面");
                        //跳转到请求密码界面
                        apiResultModel.setErrorCode(ErrorCodeConstants.Code.COACH_PWD_EP.getCode());
                        apiResultModel.setMsg(ErrorCodeConstants.Code.COACH_PWD_EP.getMessage());
                        return ResponseTools.CallBackResultJsonP(JsonTools.jsonSer(apiResultModel), callback);
                    } else {
                        log.info("教练 已经绑定过教练");
                        //已经绑定过教练
                        apiResultModel.setErrorCode(ErrorCodeConstants.Code.COACH_ALREADY_BIND.getCode());
                        apiResultModel.setMsg(ErrorCodeConstants.Code.COACH_ALREADY_BIND.getMessage());
                        return ResponseTools.CallBackResultJsonP(JsonTools.jsonSer(apiResultModel), callback);
                    }
                } else {
                    //如果教练不存在 再次查询系统用户是否存在
                    log.info("教练/系统用户  教练不存在 现在查询系统用户是否存在");
                    sysUser = accessService.querySysUserByMobile(mobile);
                    if (sysUser != null) {
                        //系统用户不为空 并且用户表中手机号码为空 将系统用户中的手机号码更新到用户表中
                        if (StringUtils.isBlank(user.getMobile())) {
                            log.info("教练/系统用户 未空说明未绑定");
                            //未空说明未绑定
                            userService.updateMobile(user.getId(), mobile);

                            UserInfo userInfo = userService.selectById(user.getId());
                            setUserInfo(userInfo);


                            log.info("教练/系统用户 跳转到请求密码界面");
                            //跳转到请求密码界面
                            apiResultModel.setErrorCode(ErrorCodeConstants.Code.COACH_PWD_EP.getCode());
                            apiResultModel.setMsg(ErrorCodeConstants.Code.COACH_PWD_EP.getMessage());

                            return ResponseTools.CallBackResultJsonP(JsonTools.jsonSer(apiResultModel), callback);
                        } else {
                            log.info("已经绑定过教练");
                            //已经绑定过教练
                            apiResultModel.setErrorCode(ErrorCodeConstants.Code.COACH_ALREADY_BIND.getCode());
                            apiResultModel.setMsg(ErrorCodeConstants.Code.COACH_ALREADY_BIND.getMessage());
                            return ResponseTools.CallBackResultJsonP(JsonTools.jsonSer(apiResultModel), callback);
                        }
                    } else {
                        log.info("非教练/系统用户 返回 绑定失败");
                        //非教练/系统用户 返回 绑定失败
                        apiResultModel.setErrorCode(ErrorCodeConstants.Code.COACH_NOT_MATCH.getCode());
                        apiResultModel.setMsg(ErrorCodeConstants.Code.COACH_NOT_MATCH.getMessage());
                        return ResponseTools.CallBackResultJsonP(JsonTools.jsonSer(apiResultModel), callback);
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.toString() + e.getCause(), e);
            apiResultModel.setRet(ApiResultModel.RET_ERROR);
            apiResultModel.setErrorCode(ErrorCodeConstants.Code.SYSTEM_ERROR_EXCEPTION.getCode());
            apiResultModel.setMsg(ErrorCodeConstants.Code.SYSTEM_ERROR_EXCEPTION.getMessage() + e.getMessage());
        }
        log.info("教练/系统用户 返回数据为 " + apiResultModel.toString());

        return ResponseTools.CallBackResultJsonP(JsonTools.jsonSer(apiResultModel), callback);
    }

    /**
     * 获取密码界面
     *
     * @return 门店列表
     */
    @RequestMapping(value = "/to_req_coach_pwd", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String getDoorInfoList(@RequestParam(defaultValue = "") String callback) {

        List<StoreInfo> storeList = storeservice.queryAllStoreList();
        ApiResultModel<Object> apiResultModel = new ApiResultModel<>();
        apiResultModel.setData(storeList);
        apiResultModel.setLogined(this.isLogined());
        return ResponseTools.CallBackResultJsonP(JsonTools.jsonSer(apiResultModel), callback);
    }

    /**
     * 获取密码请求
     *
     * @param storeId 门店ID(必传参数)
     * @return 密码显示界面 密码
     */
    @RequestMapping(value = "/req_coach_pwd", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String reqCoachPwd(@RequestParam(required = false) Integer storeId, @RequestParam(defaultValue = "") String callback) {

        ApiResultModel<Object> apiResultModel = new ApiResultModel<>();
        try {
            List<DoorAccessPwd> accessPwdList = null;
            if (storeId != null) {
                CoachInfo coachUser = coachService.queryCoachByMobile(getUserInfo().getMobile());
                if (coachUser != null) {
                    //教练密码创建
                    accessService.createCoachOrSysUserPwd(getUserInfo().getMobile(), storeId, 1);
                } else {
                    SysUser sysUser = accessService.querySysUserByMobile(getUserInfo().getMobile());
                    if (sysUser != null) {
                        //系统用户密码创建
                        accessService.createCoachOrSysUserPwd(getUserInfo().getMobile(), storeId, 2);
                    }
                }
            }
            accessPwdList = accessService.queryDoorPwdByMobile(getUserInfo().getMobile());
            if (accessPwdList != null && accessPwdList.size() > 0) {
                apiResultModel.setData(accessPwdList);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("根据门店ID-> " + storeId + "获取密码时出错 " + e.toString() + e.getCause(), e);
        }
        log.info("获取密码请求返回 --->" + apiResultModel.getData().toString());
        apiResultModel.setLogined(this.isLogined());
        return ResponseTools.CallBackResultJsonP(JsonTools.jsonSer(apiResultModel), callback);
    }


    /**
     * 校验教练手机号码是否已经绑定
     *
     * @return true 绑定/false 未绑定
     */
    @RequestMapping(value = "/check_if_isCoach", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String checkCoach(@RequestParam(defaultValue = "") String callback) {

        UserInfo userInfo = getUserInfo();
        log.info("userInfo ---> " + userInfo + "userId ===> " + userInfo.getId());
        ApiResultModel<Object> apiResultModel = new ApiResultModel<>();
        apiResultModel.setLogined(isLogined());
        Map<String, Object> resultMap = new HashMap<>();
        if (userInfo != null && StringUtils.isNotBlank(userInfo.getMobile())) {
            //首先查询教练表中教练是否存在
            CoachInfo coachInfo = coachService.queryCoachByMobile(userInfo.getMobile());
            if (coachInfo != null) {
                resultMap.put("isCoach", Boolean.TRUE);
                List<DoorAccessPwd> accessPwdList = accessService.queryDoorPwdByCoachId(coachInfo.getId());
                if (accessPwdList != null && accessPwdList.size() > 0) {
                    resultMap.put("isHavePwd", Boolean.TRUE);
                }
            } else {
                //如不存在再次查询系统用户表是否存在
                SysUser sysUser = accessService.querySysUserByMobile(userInfo.getMobile());
                if (sysUser != null) {
                    resultMap.put("isCoach", Boolean.TRUE);
                    List<DoorAccessPwd> accessPwdList = accessService.querySystemUserPwdBySysUserId(sysUser.getId());
                    if (accessPwdList != null && accessPwdList.size() > 0) {
                        resultMap.put("isHavePwd", Boolean.TRUE);
                    }
                } else {
                    resultMap.put("isCoach", Boolean.FALSE);
                    resultMap.put("isHavePwd", Boolean.FALSE);
                }
            }
        } else {
            //教练及管理后台全没有此用户手机号码记录
            resultMap.put("isCoach", Boolean.FALSE);
            resultMap.put("isHavePwd", Boolean.FALSE);
        }
        apiResultModel.setData(resultMap);
        return ResponseTools.CallBackResultJsonP(JsonTools.jsonSer(apiResultModel), callback);
    }
}
